// 8位宽字符
#define PCRE2_CODE_UNIT_WIDTH 8

#include<stdio.h>
#include<string.h>
#include<pcre2.h>

int is_valid_int(const char *s, const char *pat);

int main()
{
    int i;
    char *s[] = {"7", "123", "-1234", "1000", "12345"};
    // 判断是否为[1, 1000]内的整数的正则表达式
    const char *pat = "^[1-9][0-9]{0,2}$|^1000$";

    for(i = 0; i < sizeof(s) / sizeof(s[0]); i++)
    {
        if(is_valid_int(s[i], pat))
        {
            printf("%s is valid int.\n", s[i]);
        }
        else
        {
            printf("%s is not valid int.\n", s[i]);
        }
    }

    return 0;
}

// 判断字符串是否为有效的整数
int is_valid_int(const char *s, const char *pat)
{
    // 正则缓存(编译后的正则表达式)
    pcre2_code *re;
    // 正则匹配返回值
    int rc;

    // 错误代码
    int errornumber;
    // 错误偏移量
    PCRE2_SIZE erroroffset;
    PCRE2_SIZE subject_length;

    // 匹配寄存器(各分组匹配起始与结束位置)
    pcre2_match_data *match_data;

    PCRE2_SPTR pattern;
    PCRE2_SPTR subject;

    pattern = (PCRE2_SPTR)pat;
    subject = (PCRE2_SPTR)s;
    subject_length = (PCRE2_SIZE)strlen((char *)subject);

    // 编译正则表达式
    re = pcre2_compile(pattern,               /* 模式(正则表达式) */
                       PCRE2_ZERO_TERMINATED, /* 模式长度('\0'终止字符串) */
                       0,                     /* 默认选项 */
                       &errornumber,          /* 错误编码 */
                       &erroroffset,          /* 错误信息偏移量 */
                       NULL);                 /* 上下文，一般取NULL */
    /* 编译失败处理. */
    if (re == NULL)
    {
        PCRE2_UCHAR buffer[256];
        pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
        printf("PCRE2 compilation failed at offset %d: %s\n",
               (int)erroroffset, buffer);
        exit(EXIT_FAILURE);
    }

    // 匹配寄存器(记录各个分组的起始结束位置，包括整体匹配的默认分组group 0)
    match_data = pcre2_match_data_create_from_pattern(re, NULL);

    // 正则匹配
    rc = pcre2_match(re,             /* 正则缓存 */
                     subject,        /* 目标字符串 */
                     subject_length, /* 目标字符串长度 */
                     0,              /* 开始匹配位置 */
                     0,              /* 选项 */
                     match_data,     /* 匹配寄存器 */
                     NULL);          /* 上下文，一般取NULL */

    // 释放内存
    pcre2_match_data_free(match_data);
    pcre2_code_free(re);

    // 返回结果
    return rc < 0 ? 0 : 1;
}
